package com.bw.module_video_detail.test_gl_surfaceview;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
 * @author ytx
 * @date 2025-10-20 13:43
 * @description
 */
public class CubeRenderer implements GLSurfaceView.Renderer {
    private final Context context;
    private int mProgram;
    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;

    // 矩阵
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    private final float[] mModelMatrix = new float[16];

    private float angle = 0;

    // 立方体顶点坐标（8个顶点）
    private final float[] cubeCoords = {
            -0.5f, -0.5f,  0.5f,  // 前面左下
            0.5f, -0.5f,  0.5f,  // 前面右下
            0.5f,  0.5f,  0.5f,  // 前面右上
            -0.5f,  0.5f,  0.5f,  // 前面左上
            -0.5f, -0.5f, -0.5f,  // 后面左下
            0.5f, -0.5f, -0.5f,  // 后面右下
            0.5f,  0.5f, -0.5f,  // 后面右上
            -0.5f,  0.5f, -0.5f   // 后面左上
    };

    // 立方体索引（12个三角形，共36个索引）
    private final short[] indices = {
            0, 1, 2, 0, 2, 3,    // 前面
            4, 6, 5, 4, 7, 6,    // 后面
            4, 0, 3, 4, 3, 7,    // 左面
            1, 5, 6, 1, 6, 2,    // 右面
            3, 2, 6, 3, 6, 7,    // 上面
            4, 5, 1, 4, 1, 0     // 下面
    };

    public CubeRenderer(Context context) {
        this.context = context;
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);

        // 初始化着色器
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, getVertexShaderCode());
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, getFragmentShaderCode());

        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);

        // 初始化顶点数据
        ByteBuffer bb = ByteBuffer.allocateDirect(cubeCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(cubeCoords);
        vertexBuffer.position(0);

        // 初始化索引数据
        ByteBuffer ib = ByteBuffer.allocateDirect(indices.length * 2);
        ib.order(ByteOrder.nativeOrder());
        indexBuffer = ib.asShortBuffer();
        indexBuffer.put(indices);
        indexBuffer.position(0);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        float ratio = (float) width / height;
        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // 计算模型矩阵（旋转立方体）
        Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.rotateM(mModelMatrix, 0, angle, 0.5f, 1.0f, 0.0f);

        // 计算 MVP 矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

        // 使用着色器程序
        GLES20.glUseProgram(mProgram);

        // 传递 MVP 矩阵到着色器
        int mvpHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        GLES20.glUniformMatrix4fv(mvpHandle, 1, false, mMVPMatrix, 0);

        // 传递顶点数据
        int positionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);

        // 绘制立方体
        GLES20.glDrawElements(
                GLES20.GL_TRIANGLES,
                indices.length,
                GLES20.GL_UNSIGNED_SHORT,
                indexBuffer
        );

        // 禁用顶点数组
        GLES20.glDisableVertexAttribArray(positionHandle);

        // 更新旋转角度
        angle += 0.5f;
    }

    private String getVertexShaderCode() {
        return "attribute vec3 aPosition;" +
                "uniform mat4 uMVPMatrix;" +
                "void main() {" +
                "  gl_Position = uMVPMatrix * vec4(aPosition, 1.0);" +
                "}";
    }

    private String getFragmentShaderCode() {
        return "precision mediump float;" +
                "void main() {" +
                "  gl_FragColor = vec4(0.5, 0.8, 1.0, 1.0);" + // 淡蓝色
                "}";
    }

    private int loadShader(int type, String shaderCode) {
        int shader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
        return shader;
    }
}